<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Leaflet</title>
    <link rel="stylesheet" href="leaflet.css" />
    <link
    rel="stylesheet"
    href="./leaflet-ruler/leaflet-ruler.css"
/>
    <script src="leaflet.js"></script>
    <!--叶片状蚂蚁路径-->
    <script src="plugins/leaflet-ant-path.js"></script>
    <!--方向插件-->
    <script src="plugins/leaflet.rotatedMarker.js"></script>
    <script
    src="./leaflet-ruler/leaflet-ruler.js"
></script>
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        height: 100%;
      }

      #map {
        height: 100vh;
      }
    </style>
  </head>

  <body>
    <div id="map"></div>

    <script>
      class AntPathPolyline {
        static polylineStyleConfig = [
          {
            color: "#006600",
            fillColor: "#006600",
            pulseColor: "#e5ffe5",
          },
          {
            color: "#0000cc",
            fillColor: "#0000cc",
            pulseColor: "#ccccff",
          },
          {
            color: "#e62f00",
            fillColor: "#e62f00",
            pulseColor: "#ffc2b3",
          },
          {
            color: "#8600b3",
            fillColor: "#8600b3",
            pulseColor: "#ecb3ff",
          },
          {
            color: "#b35900",
            fillColor: "#b35900",
            pulseColor: "#ffd9b3",
          },
          {
            color: "#ff9900",
            fillColor: "#ff9900",
            pulseColor: "#ffe0b3",
          },
          {
            color: "#00b2b3",
            fillColor: "#00b2b3",
            pulseColor: "#b3ffff",
          },
          {
            color: "#000000",
            fillColor: "#000000",
            pulseColor: "#FFFFFF",
          },
          {
            color: "#006699",
            fillColor: "#006699",
            pulseColor: "#b3e6ff",
          },
          {
            color: "#cc0099",
            fillColor: "#cc0099",
            pulseColor: "#ffb3ec",
          },
        ];

        static carIconConfig = [
          "./icons/car0.png",
          "./icons/car1.png",
          "./icons/car2.png",
          "./icons/car3.png",
          "./icons/car4.png",
          "./icons/car5.png",
          "./icons/car6.png",
          "./icons/car7.png",
          "./icons/car8.png",
          "./icons/car9.png",
        ];

        static positionIconConfig = ["./icons/nav1.svg", "./icons/nav2.svg", "./icons/nav3.svg", "./icons/nav4.svg"];

        static layerGroups = {};

        // 获取当前位置方向
        static calculateBearing(lat1, lon1, lat2, lon2) {
          const dLon = (lon2 - lon1) * (Math.PI / 180);
          const y = Math.sin(dLon) * Math.cos(lat2 * (Math.PI / 180));
          const x =
            Math.cos(lat1 * (Math.PI / 180)) *
              Math.sin(lat2 * (Math.PI / 180)) -
            Math.sin(lat1 * (Math.PI / 180)) *
              Math.cos(lat2 * (Math.PI / 180)) *
              Math.cos(dLon);
          let bearing = Math.atan2(y, x) * (180 / Math.PI);

          // 将方位角规范化为0到360度之间
          if (bearing < 0) {
            bearing = (bearing + 360) % 360;
          }

          return bearing;
        }

        // 生成随机字符串
        static generateUniqueChar() {
          // 获取当前时间戳，确保每次调用都是唯一的
          const timestamp = new Date().getTime().toString(36);
          // 生成一个随机数，并转换为36进制字符串
          const randomValue = Math.random().toString(36).substr(2, 9);
          // 返回时间戳和随机数的组合，确保唯一性
          return timestamp + randomValue;
        }

        drawPolyline(
          map,
          points,
          polylineStyle,
          carIcon,
          layerGroupName,
          otherPoints
        ) {
          if (points.length === 0) {
            return;
          }

          if (AntPathPolyline.layerGroups[layerGroupName]) {
            map.removeLayer(AntPathPolyline.layerGroups[layerGroupName]);
            AntPathPolyline.layerGroups[layerGroupName] =
              L.layerGroup().addTo(map);
          } else {
            AntPathPolyline.layerGroups[layerGroupName] =
              L.layerGroup().addTo(map);
          }

          // 起始点
          const marker = L.marker(points[0], {
            icon: L.icon({
              iconUrl: AntPathPolyline.positionIconConfig[0], // 图标图片的URL
              iconSize: [32, 32], // 图标的大小
              iconAnchor: [15, 15], // 图标的锚点，即图标的位置应该放置在地图上的位置
              popupAnchor: [-3, -76], // 弹出框的锚点，即当你点击图标时，弹出框应该出现在哪个位置
            }),
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          // 线
          L.polyline
            .antPath(points, {
              ...polylineStyle,
              opacity: 6,
              delay: 10000,
              dashArray: [5, 30],
            })
            .addTo(AntPathPolyline.layerGroups[layerGroupName]);

          // 最新的点
          L.marker(points[points.length - 1], {
            icon: L.icon({
              iconUrl: carIcon,
              iconSize: [30, 30], // icon的大小
              iconAnchor: [16, 15], // icon的渲染的位置（相对与marker）
              shadowAnchor: [0, 0], // shadow的渲染的位置（相对于marker）
              popupAnchor: [0, 0], //若是绑定了popup的popup的打开位置（相对于icon）
            }),
            title: "test",
            draggable: true,
            rotationAngle:
              points.length > 1
                ? AntPathPolyline.calculateBearing(
                    points[points.length - 2][0],
                    points[points.length - 2][1],
                    points[points.length - 1][0],
                    points[points.length - 1][1]
                  )
                : 0,
          }).addTo(AntPathPolyline.layerGroups[layerGroupName]);

          // 位置集合
          for (let i = 0; i < otherPoints.length; i++) {
            const otherMarker = L.marker(otherPoints[i], {
              icon: L.icon({
                iconUrl: AntPathPolyline.positionIconConfig[3], // 图标图片的URL
                iconSize: [32, 32], // 图标的大小
                iconAnchor: [15, 15], // 图标的锚点，即图标的位置应该放置在地图上的位置
                popupAnchor: [-3, -76], // 弹出框的锚点，即当你点击图标时，弹出框应该出现在哪个位置
              }),
            })
              .addTo(AntPathPolyline.layerGroups[layerGroupName])
              .bindPopup('<a href="https://img1.baidu.com/it/u=4211738938,219568143&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500" target="_blank"><img src="https://img1.baidu.com/it/u=4211738938,219568143&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500" width="80" height="80"/></img>',
              { permanent: false, direction: "top", offset: [3, 80] })
              .openPopup();
          }
        }
      }

      const map = L.map("map").setView([39.898457, 116.391844], 13);

      L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
        minZoom: 7,
        maxZoom: 16,
        attribution: "&copy; contributors",
      }).addTo(map);

      L.control.ruler().addTo(map);

      const newPoints1 = [
        [39.898457, 116.391844],
        [39.898595, 116.377947],
        [39.898341, 116.368001],
        [39.898063, 116.357144],
        [39.899095, 116.351934],
        [39.905871, 116.35067],
        [39.922329, 116.3498],
        [39.931017, 116.349671],
        [39.939104, 116.349225],
        [39.942233, 116.34991],
        [39.947263, 116.366892],
        [39.947568, 116.387537],
        [39.947764, 116.401988],
        [39.947929, 116.410824],
        [39.947558, 116.42674],
        [39.9397, 116.427338],
        [39.932404, 116.427919],
        [39.923109, 116.428377],
        [39.907094, 116.429583],
        [39.906858, 116.41404],
        [39.906622, 116.405321],
        [39.906324, 116.394954],
        [39.906308, 116.391264],
        [39.916611, 116.390748],
      ];

      const makePolyLine = new AntPathPolyline();
      const testName1 = AntPathPolyline.generateUniqueChar();

      makePolyLine.drawPolyline(
        map,
        newPoints1,
        AntPathPolyline.polylineStyleConfig[0],
        AntPathPolyline.carIconConfig[0],
        testName1,
        newPoints1
      );
    </script>
  </body>
</html>
